arm64架构linux内核地址转换

您所在的位置:网站首页 arm64 地址空间 arm64架构linux内核地址转换

arm64架构linux内核地址转换

2023-03-04 11:37| 来源: 网络整理| 查看: 265

本文基于:linux-5.11  

 

在基于arm64架构的linux内核中, 有两个 表示__pa(x)和__va(x)用于物理地址转换位虚拟地址 或者 虚拟地址转换为物理地址(实际上还有一个__pa_symbol(x))。

这两个表达式是如何进行虚/实地址转换的?这种转换关系是如何确立的?为什么这样转换?

本文就这些问题进行挖掘探究。

一、层层展开,还原__pa(x)全貌 

表达式__pa(x)是一个宏,定义在arch/arm64/include/asm/memory.h文件中:

#define __pa(x) __virt_to_phys((unsigned long)(x))

上面的__virt_to_phys()在调试配置没有开 CONFIG_DEBUG_VIRTUAL=n 时也由宏定义在arch/arm64/include/asm/memory.h:

#define __virt_to_phys(x) __virt_to_phys_nodebug(x)

上面的 __virt_to_phys_nodebug 是一个宏,还是定义在同一个文件中:

#define __virt_to_phys_nodebug(x) ({ \ phys_addr_t __x = (phys_addr_t)(__tag_reset(x)); \ __is_lm_address(__x) ? __lm_to_phys(__x) : __kimg_to_phys(__x); \ })

这个就是arm64架构linux内核中__pa(x)的全貌。

其中,__tag_reset(x)是去掉虚拟地址中的tag(如果有tag的话),让虚拟地址还原为真正可用的虚拟地址,我们这里可以直接理解为没有tag的普通虚拟地址。

接着,第二条指令"__is_lm_address(__x) ? __lm_to_phys(__x) : __kimg_to_phys(__x)",判断虚拟地址__x是否是在线性区域,如果是则用__lm_to_phys(__x)将虚拟地址转换为物理地址;否则用__kimg_to_phys(__x)将虚拟地址转换为物理地址。

这里出现了三个表达式:__is_lm_address(),__lm_to_phys()以及__kimg_to_phys(),它们都是什么含义呢?接下来一一分析。

1.1 判断虚拟地址是否为线性地址

宏__is_lm_address(addr)用于判断虚拟地址addr是否在arm64的虚拟地址空间的线性地址区域,其实现如下:

/* * Check whether an arbitrary address is within the linear map, which * lives in the [PAGE_OFFSET, PAGE_END) interval at the bottom of the * kernel's TTBR1 address range. */ #define __is_lm_address(addr) (((u64)(addr) - PAGE_OFFSET) < (PAGE_END - PAGE_OFFSET))

这个宏判断虚拟地址addr是否处于[PAGE_OFFSET, PAGE_END)范围,如果是则说明addr是线性区域的虚拟地址。

在arm64架构中对于虚拟地址空间为48-bit (CONFIG_ARM64_VA_BITS=48是典型的有效虚拟地址配置,还有39-bit和52-bit可选) 的情况,

PAGE_OFFSET = (-(UL(1)


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3